package com.zy.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.zy.bean.qo.LiteflowSearchQo;
import com.zy.bean.vo.LiteflowChainVo;
import com.zy.core.ElNode;
import com.zy.exception.ExpressLanguageParseException;
import com.zy.parser.ElParser;
import com.zy.parser.logicflow.LogicFlow;
import com.zy.parser.logicflow.LogicFlowParser;
import com.zy.service.LiteflowChainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.fatewa.engine.advice.annotations.OriginalResponse;
import org.fatewa.engine.advice.exception.RayquazaException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

/**
 * liteflow相关的接口
 *
 * @author hanhuafeng
 * @version V1.0
 * @description
 * @date 2023/6/5
 */
@RestController
@RequestMapping("/v1/flow")
@RequiredArgsConstructor
@Slf4j
public class FlowController {
    private final LiteflowChainService liteflowChainService;

    /**
     * 分页查询liteflow编排规则流程
     *
     * @param qo 查询入参
     * @return 分页结果
     */
    @GetMapping("")
    public IPage<LiteflowChainVo> selectLiteflowChainByPage(LiteflowSearchQo qo) {
        return liteflowChainService.selectLiteflowChainByPage(qo);
    }

    /**
     * 保存流程图
     *
     * @param chartCode   流程图编码
     * @param versionCode 版本编码
     * @param logicFlow   流程图
     * @return 返回编排规则的id
     * @throws JsonProcessingException json转换异常
     */
    @PostMapping("/chart/{chartCode}/{versionCode}")
    public String saveFlowChart(@PathVariable(value = "chartCode") String chartCode,
                                @PathVariable(value = "versionCode") String versionCode,
                                @RequestBody LogicFlow logicFlow) throws JsonProcessingException {
        return liteflowChainService.saveFlowChart(chartCode, versionCode, logicFlow);
    }

    /**
     * 更新流程图节点信息和规则编排信息
     *
     * @param chartCode   流程图编码
     * @param versionCode 版本编码
     * @param logicFlow   流程图
     * @return 返回编排规则的id
     * @throws JsonProcessingException json转换异常
     */
    @PatchMapping("/chart/{chartCode}/{versionCode}")
    public String updateFlowChart(@PathVariable(value = "chartCode") String chartCode,
                                  @PathVariable(value = "versionCode") String versionCode,
                                  @RequestBody LogicFlow logicFlow) throws JsonProcessingException {
        return liteflowChainService.updateFlowChart(chartCode, versionCode, logicFlow);
    }

    /**
     * 转化el表达式
     *
     * @param elNode 节点
     * @return el表达式
     */
    @PostMapping("/generateEL")
    public String generateEl(@RequestBody ElNode elNode) {
        String sqlTemplate = null;
        try {
            sqlTemplate = elNode.generateEl();
        } catch (ExpressLanguageParseException e) {
            log.error("", e);
        }
        return sqlTemplate;
    }

    /**
     * logicFlow转化el表达式
     *
     * @param logicFlow logicFlow数据节点
     * @return el表达式
     */
    @PostMapping("/generateLogicFlowEL")
    public String generateLogicFlowEl(@RequestBody LogicFlow logicFlow) {
        String sqlTemplate = null;
        try {
            ElParser elParser = new LogicFlowParser(logicFlow);
            ElNode elNode = elParser.extractElNode();
            sqlTemplate = elNode.generateEl();
        } catch (ExpressLanguageParseException e) {
            log.error("", e);
            throw new RayquazaException(HttpStatus.INTERNAL_SERVER_ERROR, "转化el表达式失败");
        }
        return sqlTemplate;
    }

    /**
     * 通过图编码和版本编码获取流程图
     *
     * @param chartCode   图编码
     * @param versionCode 版本编码
     * @return 流程图
     */
    @GetMapping("/{chartCode}/link")
    public LogicFlow getLogicFlowLinkByCodeAndVersion(@PathVariable("chartCode") String chartCode,
                                                      @RequestParam("versionCode") String versionCode) throws JsonProcessingException {
        return liteflowChainService.getLogicFlowLinkByCodeAndVersion(chartCode, versionCode);
    }

    /**
     * 执行流程
     *
     * @param chainName 流程名称
     * @return 执行结果
     */
    @PostMapping("/execute")
    @OriginalResponse
    public LiteflowResponse execute(String chainName, @RequestBody(required = false) Object param) {
        return liteflowChainService.execute(chainName, param);
    }
}
